package gui.components;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import network.client.WhiteboardClient;
import network.server.WhiteboardServer;
import controller.Constants;
import controller.NetworkController;

/**
 * A host dialog provides a ui which allows the user to start a server on a
 * given port and password.
 * 
 * @author Jie Zhao(288654)
 * 
 */
public class HostDialog extends JDialog {
	private static final long serialVersionUID = 1L;
	private final JLabel serverPortLabel = new JLabel();
	private final JTextField tfPort = new JTextField();
	private final JButton connectButton = new JButton();
	private final JButton cancelButton = new JButton();

	private WhiteboardServer server = null;

	private int port = 0;
	private int returnvalue = -1;
	private String password = null;
	private String username = null;

	private final JLabel passwordLabel = new JLabel();
	private final JTextField tfPassword = new JTextField();
	private final JLabel yourNameLabel = new JLabel();
	private final JTextField tfUsername = new JTextField();

	@Override
	public void setVisible(boolean b) {
		if (b == true) {
			returnvalue = -1;
		}
		super.setVisible(b);
	}

	public HostDialog() {
		super();
		try {
			jbInit();
		} catch (Throwable e) {
			e.printStackTrace();
		}

	}

	private void jbInit() throws Exception {
		setTitle("Host");
		setSize(347, 201);
		setName("HostDialog");
		setModal(true);
		getContentPane().setLayout(null);
		setResizable(false);

		getContentPane().add(serverPortLabel);
		serverPortLabel.setText("Server Port:");
		serverPortLabel.setBounds(12, 22, 77, 16);

		getContentPane().add(tfPort);
		tfPort.addKeyListener(new TfPortKeyListener());
		tfPort.setColumns(5);
		tfPort.setBounds(116, 20, 218, 20);

		getContentPane().add(connectButton);
		connectButton.addActionListener(new ConnectButtonActionListener());
		connectButton.setText("Connect");
		connectButton.setBounds(92, 136, 106, 26);

		getContentPane().add(cancelButton);
		cancelButton.addActionListener(new CancelButtonActionListener());
		cancelButton.setText("Cancel");
		cancelButton.setBounds(225, 136, 106, 26);
		final FlowLayout flowLayout = new FlowLayout();
		flowLayout.setAlignment(FlowLayout.LEADING);

		if (Constants.DEBUG) {
			tfPort.setText("1234");
		}

		getContentPane().add(passwordLabel);
		passwordLabel.setText("Password:");
		passwordLabel.setBounds(12, 57, 66, 16);

		getContentPane().add(tfPassword);
		tfPassword.setBounds(116, 55, 218, 20);

		getContentPane().add(yourNameLabel);
		yourNameLabel.setText("Your Name:");
		yourNameLabel.setBounds(12, 93, 66, 16);

		getContentPane().add(tfUsername);
		tfUsername.setBounds(116, 91, 215, 20);
	}

	private class TfPortKeyListener extends KeyAdapter {
		public void keyPressed(KeyEvent e) {
			tfPort_keyPressed(e);
		}
	}

	private class ConnectButtonActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			connectButton_actionPerformed(e);
		}
	}

	private class CancelButtonActionListener implements ActionListener {
		public void actionPerformed(ActionEvent e) {
			cancelButton_actionPerformed(e);
		}
	}

	protected void tfPort_keyPressed(KeyEvent e) {

		char c = e.getKeyChar();
		if (c == KeyEvent.VK_ENTER) {
			connectButton_actionPerformed(null);
		} else if (!Character.isISOControl(c) && !Character.isDigit(c)) {
			JOptionPane.showMessageDialog(null, "Port should be digit only!");
		}
	}

	private WhiteboardClient client = null;

	protected boolean verify() {
		String p = tfPort.getText();
		password = tfPassword.getText();
		username = tfUsername.getText();
		if (p == null || p.equals("")) {
			JOptionPane.showMessageDialog(null,
					"Please input server port before hosting");
			return false;
		} else if (username == null || username.equals("")) {
			JOptionPane.showMessageDialog(null, "Please give a username");
			return false;
		} else {
			try {
				port = Integer.parseInt(p);
			} catch (Exception e) {
				JOptionPane.showMessageDialog(null,
						"Port should be number only");
				return false;
			}
			if (port < 1 || port > 65534) {
				JOptionPane.showMessageDialog(null,
						"Port range should between 1-65534");
				return false;
			}
			try {
				server = new WhiteboardServer();
				server.setPort(port);
				server.setPassword(password);
				server.start();
				client = new WhiteboardClient();

				NetworkController.getInstance().setClient(client);
				NetworkController.getInstance().setServer(server);
				NetworkController.getInstance().setUsername(username);
				boolean isSuccess = client.connect("localhost", port, username,
						password);
			} catch (Exception e) {
				JOptionPane.showMessageDialog(null,
						"Unable to start server, Reason:" + e.getMessage());
				return false;
			}
		}
		return true;
	}

	protected void connectButton_actionPerformed(ActionEvent e) {
		if (verify()) {
			this.setVisible(false);
			returnvalue = 0;
		}
	}

	protected void cancelButton_actionPerformed(ActionEvent e) {
		this.setVisible(false);
		returnvalue = 1;
	}

	public int getPort() {
		return port;
	}

	public int getReturnvalue() {
		return returnvalue;
	}

	public WhiteboardServer getServer() {
		return server;
	}
}
